#include "arduino_timer.h"
#include <string.h>

/**
 * 初始化定时器管理器
 * 功能：绑定系统时间获取函数，初始化定时器链表
 */
void timer_manager_init(TimerManager* manager, uint32_t (*get_tick_ms)()) {
    if (manager == NULL || get_tick_ms == NULL) return;
    manager->timers = NULL;          // 初始化链表为空
    manager->get_tick_ms = get_tick_ms;  // 绑定系统时间函数
}

/**
 * 初始化单个定时器
 * 功能：设置定时器参数，初始状态为停止
 */
void timer_init(Timer* timer, TimerMode mode, uint32_t interval,
               TimerCallback callback, void* user_data) {
    if (timer == NULL || callback == NULL || interval == 0) return;
    memset(timer, 0, sizeof(Timer)); // 清空定时器数据
    timer->mode = mode;
    timer->interval = interval;
    timer->callback = callback;
    timer->user_data = user_data;
    timer->state = TIMER_STATE_STOPPED; // 初始为停止状态
}

/**
 * 将定时器加入管理器链表（内部辅助函数）
 */
static void timer_add(TimerManager* manager, Timer* timer) {
    if (manager == NULL || timer == NULL) return;
    // 头插法加入链表
    timer->next = manager->timers;
    manager->timers = timer;
}

/**
 * 将定时器从管理器链表移除（内部辅助函数）
 */
static void timer_remove(TimerManager* manager, Timer* timer) {
    if (manager == NULL || timer == NULL || manager->timers == NULL) return;
    Timer**prev = &manager->timers;
    // 遍历链表找到目标定时器
    while (*prev != NULL) {
        if (*prev == timer) {
            *prev = timer->next; // 跳过当前节点
            break;
        }
        prev = &(*prev)->next;
    }
}

/**
 * 启动定时器
 * 功能：设置启动时间，加入链表，标记为运行状态
 */
void timer_start(TimerManager* manager, Timer* timer) {
    if (manager == NULL || timer == NULL || timer->state == TIMER_STATE_RUNNING) return;
    // 记录当前时间作为基准（下次触发时间 = 当前时间 + 间隔）
    timer->last_trigger = manager->get_tick_ms();
    timer->state = TIMER_STATE_RUNNING;
    timer_add(manager, timer); // 加入管理器链表
}

/**
 * 停止定时器
 * 功能：从链表移除，标记为停止状态
 */
void timer_stop(TimerManager* manager, Timer* timer) {
    if (manager == NULL || timer == NULL || timer->state == TIMER_STATE_STOPPED) return;
    timer_remove(manager, timer); // 从链表移除
    timer->state = TIMER_STATE_STOPPED;
}

/**
 * 检查定时器是否超时（内部辅助函数）
 * 处理毫秒级溢出（如32位溢出后从0重新计数的情况）
 */
static bool timer_is_expired(Timer* timer, uint32_t current_ms) {
    uint32_t elapsed;
    // 处理时间溢出：若当前时间 < 上次触发时间，说明发生了溢出
    if (current_ms >= timer->last_trigger) {
        elapsed = current_ms - timer->last_trigger;
    } else {
        // 溢出情况下的时间计算（假设32位uint，最大值为0xFFFFFFFF）
        elapsed = (0xFFFFFFFF - timer->last_trigger) + current_ms + 1;
    }
    return elapsed >= timer->interval;
}

/**
 * 定时器处理函数（核心算法）
 * 功能：遍历所有运行中的定时器，检查是否超时并触发回调
 */
void timer_process(TimerManager* manager) {
    if (manager == NULL || manager->get_tick_ms == NULL) return;
    uint32_t current_ms = manager->get_tick_ms(); // 获取当前系统时间
    Timer* current = manager->timers;
    Timer* next;

    // 遍历所有定时器（提前保存next，防止回调中删除当前定时器导致链表断裂）
    while (current != NULL) {
        next = current->next; // 保存下一个节点

        if (current->state == TIMER_STATE_RUNNING) {
            // 检查是否超时
            if (timer_is_expired(current, current_ms)) {
                // 执行回调函数
                current->callback(current->user_data);

                // 根据模式处理后续状态
                if (current->mode == TIMER_MODE_ONE_SHOT) {
                    // 单次模式：触发后停止
                    timer_stop(manager, current);
                } else {
                    // 周期模式：更新上次触发时间，继续运行
                    current->last_trigger = current_ms;
                }
            }
        }

        current = next; // 处理下一个定时器
    }
}